package com.qianfeng.chainmobile.api.service.impl;

import com.qianfeng.chainmobile.api.bean.CheckResultBean;
import com.qianfeng.chainmobile.api.dto.SmsParamBody;
import com.qianfeng.chainmobile.api.dto.SmsParamBodyContent;
import com.qianfeng.chainmobile.api.dto.SmsParamBodyTemp;
import com.qianfeng.chainmobile.api.event.SendMessageEvent;
import com.qianfeng.chainmobile.api.exceptions.MyExceptionWithData;
import com.qianfeng.chainmobile.api.feign.CacheService;
import com.qianfeng.chainmobile.api.service.SmsService;
import com.qianfeng.chainmobile.api.utils.PhoneFormatCheckUtil;
import com.qianfeng.smsplatform.common.constants.CacheConstants;
import com.qianfeng.smsplatform.common.constants.InterfaceExceptionDict;
import com.qianfeng.smsplatform.common.exceptions.MyBaseException;
import com.qianfeng.smsplatform.common.model.Standard_Submit;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;
import org.springframework.util.ObjectUtils;

import java.nio.charset.StandardCharsets;
import java.util.*;

@Service
public class SmsServiceImpl implements SmsService {

    private ApplicationContext context;
    @Autowired
    public void setContext(ApplicationContext context) {
        this.context = context;
    }

    private CacheService cacheService;
    @Autowired
    public void setCacheService(CacheService cacheService) {
        this.cacheService = cacheService;
    }

    @Override
    public void sendMsgByContent(SmsParamBodyContent bodyContent, String ip) {
        CheckResultBean checkResultBean = checkData(bodyContent, ip);

        List<String> failPhones = checkResultBean.getFailPhones();
        List<Standard_Submit> standard_submitList = checkResultBean.getStandard_submitList();
        //继续后面的操作,可以通过异步发消息，不用让客户等待
        context.publishEvent(new SendMessageEvent(standard_submitList));
        if (failPhones != null && failPhones.size()>0) {
            MyExceptionWithData exception = new MyExceptionWithData("非法手机号或者对应的内容为空", InterfaceExceptionDict.RETURN_STATUS_MOBILE_ERROR);
            exception.setData(failPhones);
            throw exception;
        }
    }

    @Override
    public CheckResultBean checkData(SmsParamBody body, String ip) {

        System.err.println("来访者的 ip" + ip);
        CheckResultBean checkResultBean = new CheckResultBean();//返回结果
        String srcId = body.getSrcId();
        if (ObjectUtils.isEmpty(srcId)) {
            System.err.println("srcId没有传递");
            throw new MyBaseException("未传递短信 id" ,InterfaceExceptionDict.RETURN_STATUS_SRCID_ERROR);
        }
        String phoneNums = body.getPhoneNums();
        if (ObjectUtils.isEmpty(phoneNums)) {
            System.err.println("手机号为空，返回结果给客户");
            throw new MyBaseException("需要传递手机号",InterfaceExceptionDict.RETURN_STATUS_MOBILE_ERROR);
        }
        String[] nums = phoneNums.split(",");
        List<String> numsList = Arrays.asList(nums);
        Map<String,String> phone2ContentMap = new HashMap<>();//保存手机号和内容
        if (body instanceof SmsParamBodyContent) {
            List<String> content = ((SmsParamBodyContent) body).getContent();

            if (ObjectUtils.isEmpty(content)) {
                throw new MyBaseException("未传递内容",InterfaceExceptionDict.RETURN_STATUS_MESSAGE_ERROR);
            }
            //内容是空的两种情况
            if (content.size()==1) {
                String oneContent = content.get(0);
                if (ObjectUtils.isEmpty(oneContent)) {
                    throw new MyBaseException("短信内容为空",InterfaceExceptionDict.RETURN_STATUS_MESSAGE_ERROR);
                }
                numsList.forEach(num ->{
                    phone2ContentMap.put(num,oneContent);
                });
            }else {
                if (numsList.size() != content.size()) {
                    throw new MyBaseException("手机号和内容不匹配",InterfaceExceptionDict.RETURN_STATUS_MESSAGE_PHONE_NOT_MATCH);
                }else {
                    for (int i = content.size()-1;i >= 0 ; i--) {
                        phone2ContentMap.put(numsList.get(i),content.get(i));
                    }
                }
            }
        }else if (body instanceof SmsParamBodyTemp) {

        }

        List<String> failPhones = new ArrayList<>();//保存不合法手机号
        phone2ContentMap.forEach((key,value) ->{
            if (!PhoneFormatCheckUtil.isChinaPhoneLegal(key) || ObjectUtils.isEmpty(value)){
                failPhones.add(key);
            }
        });
        failPhones.forEach(num ->{
            phone2ContentMap.remove(num);
        });
        System.err.println(failPhones);
        System.err.println(phone2ContentMap);

        if (failPhones.size() > 0) {
            //不能抛异常，抛了之后后面的手机号也不发送了，直接告诉用户
            checkResultBean.setFailPhones(failPhones);
        }
        //从缓存中获取用户信息
        Map userinfoMap = cacheService.hmget(CacheConstants.CACHE_PREFIX_CLIENT + body.getUsercode());
        if (userinfoMap == null) {
            throw new MyBaseException("认证失败" ,InterfaceExceptionDict.RETURN_STATUS_CLIENTID_ERROR);
        }

        String password = body.getPassword();
        String pwd = (String) userinfoMap.get("pwd");
        String md5DigestAsHex = DigestUtils.md5DigestAsHex(password.getBytes(StandardCharsets.UTF_8));
        if (!md5DigestAsHex.equals(pwd)) {
            throw new MyBaseException("认证失败" ,InterfaceExceptionDict.RETURN_STATUS_CLIENTID_ERROR);
        }
        String ipaddress = (String) userinfoMap.get("ipaddress");

        if (!ipaddress.contains(ip)) {
            throw new MyBaseException("非白名单" ,InterfaceExceptionDict.RETURN_STATUS_IP_ERROR);
        }

        //生成数据
        List<Standard_Submit> standard_submits = new ArrayList<>();
        phone2ContentMap.forEach((num ,content) ->{
            Standard_Submit standard_submit = new Standard_Submit();
            standard_submit.setCityId(body.getUsercode());
            standard_submit.setDestMobile(num);
            standard_submit.setMessageContent(content);
            standard_submit.setSrcNumber(srcId);
            standard_submit.setSendTime(new Date());
            //设置用户类型，是1的话后续需要通知对方
            standard_submit.setSource((Integer) userinfoMap.get("usertype"));
            standard_submits.add(standard_submit);
        });
        checkResultBean.setStandard_submitList(standard_submits);

        return checkResultBean;
    }
}
